import { useRoleStore } from "@/store"
import type { Ref } from "vue"
import type { CommonTypeItem, CompDetaileConfigItem } from "@/store/modules/role/types"
interface FormType {
  name: string 
  description: string 
  permIds: number[]
}
interface DialogInject {
  addRoleForm: Ref<{name: string, description: string, permIds: number[]}>
  checkall: Ref<boolean>
  indeterminate: Ref<boolean>
  setCheckVal: (val: boolean) => void
  setIndetVal: (val: boolean) => void
}

const useUtils = () => {
  const roleStore = useRoleStore()

  /**
   * 改变第一层菜单复选框值
   * @param checked 当前选中状态
   * @param currentItem 当前选择数据项
   * @param dialogState 依赖注入的state
   */
  const switchFirstLevel = (checked: boolean, currentItem: CommonTypeItem, dialogState: DialogInject) => {
    currentItem.indeterminate = false
    // 获取第二层id集合
    const pageIds = getCurrentData(currentItem, "pageConfig", checked)
    // 获取第二层每一项集合
    const pageArr = Object.values(roleStore.pageConfig).filter(item => item.parentCode === currentItem.code)
    // 获取第三层id集合
    pageArr.map(pageItem => {
      // 获取第三层id集合
      const componentIds = getCurrentData(pageItem, "componentConfig", checked)
      // 获取最后一层id集合
      const componentDetailIds = getCurrentData(pageItem, 'compDetaileConfig', checked, true)
      if (checked) {
        // 选中时将id集合整合
        dialogState.addRoleForm.value.permIds = [
          ...dialogState.addRoleForm.value.permIds,
          ...componentIds,
          ...componentDetailIds
        ]
      } else {
        // 未选中将id移除
        dialogState.addRoleForm.value.permIds = dialogState.addRoleForm.value.permIds.filter(item => !componentIds.includes(item) && !componentDetailIds.includes(item))
      }
    })
    if (checked) {
      // 选中时将id集合整合
      dialogState.addRoleForm.value.permIds = [
        ...dialogState.addRoleForm.value.permIds,
        currentItem.id,
        ...pageIds
      ]
    } else {
      // 未选中将id移除
      dialogState.addRoleForm.value.permIds = dialogState.addRoleForm.value.permIds.filter(item => item !== currentItem.id && !pageIds.includes(item))
    }
    // console.log(dialogState.addRoleForm.value.permIds, "switchFirstLevel");
    // 处理全选
    switchCheckAllStatus(dialogState)
  }

  /**
   * 改变第二层菜单复选框值
   * @param checked 当前选中状态
   * @param currentItem 当前选择数据项
   * @param dialogState 依赖注入的state
   */
  const switchSecondLevel = (checked: boolean, currentItem: CommonTypeItem, dialogState: DialogInject) => {
    // 通过当前项找父级项(第一层)
    const findParentItem = roleStore.moduleConfig[currentItem.parentCode!]
    // 获取第三层id集合
    const componentIds = getCurrentData(currentItem, 'componentConfig', checked)
    // 获取最后一层id集合
    const componentDetailIds = getCurrentData(currentItem, 'compDetaileConfig', checked, true)
    currentItem.indeterminate = false
    // 通过父级项获取第二层当前数据集合
    const filterArr = Object.values(roleStore.pageConfig).filter(item => item.parentCode === findParentItem.code)
    // 将第二层数据集合转换成布尔值集合
    const flagArr = filterArr.map(item => item.checked)
    const flagIndetArr = filterArr.map(item => item.indeterminate)
    // 设置第二层选中状态
    const firstStatus = calCheckStatus(flagArr, flagIndetArr)
    findParentItem.checked = firstStatus.checked
    findParentItem.indeterminate = firstStatus.indeterminate
    if (checked) {
      // 选中时将id集合整合
      !dialogState.addRoleForm.value.permIds.includes(findParentItem.id) && dialogState.addRoleForm.value.permIds.push(findParentItem.id)
      dialogState.addRoleForm.value.permIds = [
        ...dialogState.addRoleForm.value.permIds,
        currentItem.id,
        ...componentIds,
        ...componentDetailIds
      ]
    } else {
      // 先移除自己id
      dialogState.addRoleForm.value.permIds = dialogState.addRoleForm.value.permIds.filter(item => item !== currentItem.id)
      // 移除自己下所有子项id
      dialogState.addRoleForm.value.permIds = dialogState.addRoleForm.value.permIds.filter(item => !componentIds.includes(item) && !componentDetailIds.includes(item))
      // 获取第二层半选状态下是否还有选中的
      const filterPageIndetCheckArr = flagIndetArr.filter(Boolean)
      // 获取第二层选中状态下是否还有选中的
      const filterPageCheckArr = flagArr.filter(Boolean)
      if (filterPageIndetCheckArr.length === 0 && filterPageCheckArr.length === 0) {
        dialogState.addRoleForm.value.permIds = dialogState.addRoleForm.value.permIds.filter(item => item !== findParentItem.id)
      }
    }
    
    // console.log(dialogState.addRoleForm.value.permIds, "switchSecondLevel");
    // 处理全选
    switchCheckAllStatus(dialogState)
  }

  /**
   * 改变第三层菜单复选框值
   * @param checked 当前选中状态
   * @param currentItem 当前选择数据项
   * @param dialogState 依赖注入的state
   */
  const switchThirdLevel = (checked: boolean, currentItem: CommonTypeItem, dialogState: DialogInject) => {
    
    // 通过当前项找父级项（父亲）
    const findParentItem = roleStore.pageConfig[currentItem.parentCode!]
    // 通过父级项找第一层项（爷爷）
    const findModuleItem = roleStore.moduleConfig[findParentItem.parentCode!]
    // 获取最后一层id集合并反选所有子项
    const componentDetailIds = getCurrentChildData(currentItem, 'compDetaileConfig', checked)
    // 改变自己当前的状态值
    currentItem.indeterminate = false
    // 通过父级项获取第三层当前数据集合
    const compArr = Object.values(roleStore.componentConfig).filter(item => item.parentCode === findParentItem.code)
    // 通过父级项获取第二层当前数据集合
    const pageArr = Object.values(roleStore.pageConfig).filter(item => item.parentCode === findModuleItem.code)
    // 将第三层数据集合转换成布尔值集合
    const compCheckArr = compArr.map(item => item.checked)
    const compIndetArr = compArr.map(item => item.indeterminate)
    //设置自己的indeterminate
    currentItem.indeterminate = false
    // 设置第二层选中状态
    const secondStatus = calCheckStatus(compCheckArr, compIndetArr)
    findParentItem.checked = secondStatus.checked
    findParentItem.indeterminate = secondStatus.indeterminate
    // 将第二层数据集合转换成布尔值集合
    const pageCheckArr = pageArr.map(item => item.checked)
    const pageIndetArr = pageArr.map(item => item.indeterminate)
    // 设置第一层选中状态
    const firstStatus = calCheckStatus(pageCheckArr, pageIndetArr)
    findModuleItem.checked = firstStatus.checked
    findModuleItem.indeterminate = firstStatus.indeterminate
    if (checked) {
      // 选中时将id集合整合
      !dialogState.addRoleForm.value.permIds.includes(findModuleItem.id) && dialogState.addRoleForm.value.permIds.push(findModuleItem.id)
      !dialogState.addRoleForm.value.permIds.includes(findParentItem.id) && dialogState.addRoleForm.value.permIds.push(findParentItem.id)
      dialogState.addRoleForm.value.permIds = [
        ...dialogState.addRoleForm.value.permIds,
        currentItem.id,
        ...componentDetailIds
      ]
    } else {
      // 先移除当前自己的id和子级所有id
      dialogState.addRoleForm.value.permIds = dialogState.addRoleForm.value.permIds.filter(item => item !== currentItem.id && !componentDetailIds.includes(item))
      // 获取第三层选中状态下是否还有选中的
      const filterCompCheckArr = compCheckArr.filter(Boolean)
      // 获取第三层半选状态下是否还有选中的
      const filterCompIndetCheckArr = compIndetArr.filter(Boolean)
      if (filterCompCheckArr.length === 0 && filterCompIndetCheckArr.length === 0) {
        dialogState.addRoleForm.value.permIds = dialogState.addRoleForm.value.permIds.filter(item => item !== findParentItem.id)
      }
      // 获取第二层选中状态下是否还有选中的
      const filterPageCheckArr = pageCheckArr.filter(Boolean)
      // 获取第二层半选状态下是否还有选中的
      const filterPageIndetArr = pageIndetArr.filter(Boolean)
      if (filterPageCheckArr.length === 0 && filterPageIndetArr.length === 0) {
        dialogState.addRoleForm.value.permIds = dialogState.addRoleForm.value.permIds.filter(item => item !== findModuleItem.id)
      }
    }
    // console.log(dialogState.addRoleForm.value.permIds, "switchThirdLevel");
    // 处理全选
    switchCheckAllStatus(dialogState)
  }

  /**
   * 改变最后一层菜单复选框值
   * @param checked 当前选中状态
   * @param currentItem 当前选择数据项
   * @param dialogState 依赖注入的state
   */
  const switchLastLevel = (checked: boolean, currentItem: CommonTypeItem, dialogState: DialogInject) => {
    // 获取当前的父级项
    const findParentItem = roleStore.compDetaileConfig[currentItem.parentCode!]
    const componentItem = roleStore.componentConfig[findParentItem.parentCode!]
    const pageItem = roleStore.pageConfig[componentItem.parentCode!]
    const moduleItem = roleStore.moduleConfig[pageItem.parentCode!]
    // 获取当前所在的布尔值集合
    const currentArr = findParentItem.children.map(item => item.checked)
    // const currentIndetArr = findParentItem.children.map(item => item.indeterminate)
    // 通过布尔值改变当前自己的父级状态
    findParentItem.checked = currentArr.every(Boolean)
    // 获取当前自己父级集合
    const parentArr = Object.values(roleStore.compDetaileConfig).filter(item => item.parentCode === findParentItem.parentCode)
    // 获取当前自己父级子级集合
    const parentChildArr: { id: number; code: string; label: string; checked: boolean; level?: number | undefined; }[] = []
    parentArr.map(item => {
      item.children.map(t => {
        parentChildArr.push(t)
      })
    })
    // 所有子级选中集合
    const parentChildCheckArr = parentChildArr.map(item => item.checked)
    // 通过父级状态数据集合改变第三层状态
    // const thirdStatus = calCheckStatus(currentArr, currentIndetArr)
    componentItem.checked = parentChildCheckArr.every(Boolean)
    componentItem.indeterminate = parentChildCheckArr.some(Boolean) && !parentChildCheckArr.every(Boolean)
    // componentItem.checked = thirdStatus.checked
    // componentItem.indeterminate = thirdStatus.indeterminate
    // 通过第三层改变第二层状态
    const componentArr = Object.values(roleStore.componentConfig).filter(item => item.parentCode === componentItem.parentCode)
    const componentCheckArr = componentArr.map(item => item.checked)
    const componentIndetArr = componentArr.map(item => item.indeterminate)
    const secondStatus = calCheckStatus(componentCheckArr, componentIndetArr)
    pageItem.checked = secondStatus.checked
    pageItem.indeterminate = secondStatus.indeterminate
    // 通过第二层改变第一层状态
    const pageArr = Object.values(roleStore.pageConfig).filter(item => item.parentCode === pageItem.parentCode)
    const pageCheckArr = pageArr.map(item => item.checked)
    const pageIndetArr = pageArr.map(item => item.indeterminate)
    const firstStatus = calCheckStatus(pageCheckArr, pageIndetArr)
    moduleItem.checked = firstStatus.checked
    moduleItem.indeterminate = firstStatus.indeterminate
    if (checked) {
      // 选中时将id集合整合
      !dialogState.addRoleForm.value.permIds.includes(moduleItem.id) && dialogState.addRoleForm.value.permIds.push(moduleItem.id)
      !dialogState.addRoleForm.value.permIds.includes(pageItem.id) && dialogState.addRoleForm.value.permIds.push(pageItem.id)
      !dialogState.addRoleForm.value.permIds.includes(componentItem.id) && dialogState.addRoleForm.value.permIds.push(componentItem.id)
      !dialogState.addRoleForm.value.permIds.includes(findParentItem.id) && dialogState.addRoleForm.value.permIds.push(findParentItem.id)
      dialogState.addRoleForm.value.permIds = [
        ...dialogState.addRoleForm.value.permIds,
        currentItem.id
      ]
    } else {
      // 先移除当前自己id
      dialogState.addRoleForm.value.permIds = dialogState.addRoleForm.value.permIds.filter(item => item !== currentItem.id)
      // 获取当前自己的选中状态下是否还有选中
      const filterCurrentArr = currentArr.filter(Boolean)
      if (filterCurrentArr.length === 0) {
        dialogState.addRoleForm.value.permIds = dialogState.addRoleForm.value.permIds.filter(item => item !== findParentItem.id)
      }
      // 获取最后一层所有子项选中状态下是否还有选中的
      const filterCompChildArr = parentChildCheckArr.filter(Boolean)
      if (filterCompChildArr.length === 0) {
        dialogState.addRoleForm.value.permIds = dialogState.addRoleForm.value.permIds.filter(item => item !== componentItem.id)
      }
      // 获取第三层选中状态下是否还有选中的
      const filterCompCheckArr = componentCheckArr.filter(Boolean)
      // 获取第三层半选状态下是否还有选中的
      const filterCompIndetCheckArr = componentIndetArr.filter(Boolean)
      if (filterCompCheckArr.length === 0 && filterCompIndetCheckArr.length === 0) {
        dialogState.addRoleForm.value.permIds = dialogState.addRoleForm.value.permIds.filter(item => item !== pageItem.id)
      }
      // 获取第二层选中状态下是否还有选中的
      const filterPageCheckArr = pageCheckArr.filter(Boolean)
      // 获取第二层半选状态下是否还有选中的
      const filterPageIndetArr = pageIndetArr.filter(Boolean)
      if (filterPageCheckArr.length === 0 && filterPageIndetArr.length === 0) {
        dialogState.addRoleForm.value.permIds = dialogState.addRoleForm.value.permIds.filter(item => item !== moduleItem.id)
      }
    }
    // console.log(dialogState.addRoleForm.value.permIds, "switchLastLevel");
    // 处理全选
    switchCheckAllStatus(dialogState)
  }

  /**
   * 改变全选菜单复选框值
   * @param checked 当前选中状态
   * @param currentItem 当前选择数据项
   * @param dialogState 依赖注入的state
   */
  const switchCheckAllStatus = (dialogState: DialogInject) => {
    const moduleArr = Object.values(roleStore.moduleConfig).map(item => item.checked)
    const moduleIndetArr = Object.values(roleStore.moduleConfig).map(item => item.indeterminate)
    const allStatus = calCheckStatus(moduleArr, moduleIndetArr)
    dialogState.setCheckVal(allStatus.checked)
    dialogState.setIndetVal(allStatus.indeterminate)
  }

  /**
   * 获取当前store中的数据id集合
   * @param key 当前store的state的key
   * @param checked 选中状态
   * @param isLast 是否为最后一项
   * @returns id集合
   */
  const getDataAndCheck = (key: string, checked: boolean, isLast: boolean = false) => {
    let arr: number[] = []
    !isLast && (arr = Object.values(roleStore[key]).map(item => {
      (item as CommonTypeItem).checked = checked
      return (item as CommonTypeItem).id
    }))
    isLast && Object.values(roleStore[key]).map(item => {
      (item as CompDetaileConfigItem).checked = checked;
      !arr.includes((item as CompDetaileConfigItem).id) && arr.push((item as CompDetaileConfigItem).id);
      (item as CompDetaileConfigItem).children && (item as CompDetaileConfigItem).children.length !== 0 && (item as CompDetaileConfigItem).children.map(t => {
        t.checked = checked
        arr.push(t.id)
      })
    })
    return arr
  }

  /**
   * 获取当前数据id集合
   * @param currentItem 当前数据项
   * @param key 当前store的state的key
   * @param checked 选中状态
   * @param isLast 是否为最后一项
   * @returns id集合
   */
  const getCurrentData = (currentItem: CommonTypeItem, key: string, checked: boolean, isLast: boolean = false) => {
    let arr: number[] = []
    !isLast && Object.values(roleStore[key]).map(item => {
      if ((item as CommonTypeItem).parentCode === currentItem.code) {
        (item as CommonTypeItem).checked = checked;
        (item as CommonTypeItem).indeterminate = false
        arr.push((item as CommonTypeItem).id)
      }
    })
    if (isLast) {
      const childItems = Object.values(roleStore.componentConfig).filter(item => item.parentCode === currentItem.code)
      childItems && childItems.length !== 0 && Object.values(roleStore[key]).map(item => {
        childItems.map(t => {
          if ((item as CommonTypeItem).parentCode === t.code) {
            !arr.includes((item as CommonTypeItem).id) && arr.push((item as CommonTypeItem).id);
            (item as CompDetaileConfigItem).checked = checked;
            (item as CompDetaileConfigItem).children && (item as CompDetaileConfigItem).children.length !== 0 && (item as CompDetaileConfigItem).children.map(t => {
              t.checked = checked
              arr.push(t.id)
            })
          }
        })
      })
    }
    return arr
  }

  /**
   * 获取最后一层当前数据id集合
   * @param currentItem 当前数据项
   * @param key 当前store的state的key
   * @param checked 选中状态
   * @returns id集合
   */
  const getCurrentChildData = (currentItem: CommonTypeItem, key: string, checked: boolean) => {
    let arr: number[] = []
    Object.values(roleStore[key]).map(item => {
      if ((item as CommonTypeItem).parentCode === currentItem.code) {
        !arr.includes((item as CommonTypeItem).id) && arr.push((item as CommonTypeItem).id);
        (item as CompDetaileConfigItem).children && (item as CompDetaileConfigItem).children.length !== 0 && (item as CompDetaileConfigItem).children.map(t => {
          t.checked = checked
          arr.push(t.id)
        })
      }
    })
    return arr
  }

  /**
   * 清除所有的复选框
   */
  const clearAllCheck = () => {
    Object.values(roleStore.moduleConfig).map(item => {
      item.isVisibile = true
      item.checked = false
      item.indeterminate = false
    })
    Object.values(roleStore.pageConfig).map(item => {
      item.checked = false
      item.indeterminate = false
    })
    Object.values(roleStore.componentConfig).map(item => {
      item.checked = false
      item.indeterminate = false
    })
    Object.values(roleStore.compDetaileConfig).map(item => {
      item.checked = false
      item.children && item.children.length !== 0 && item.children.map(t => {
        t.checked = false
      })
    })
  }

  const setCheckedStatus = (ids: number[], checkall: Ref<boolean>, indeterminate: Ref<boolean>) => {
    // 根据id集合处理最后一层选择
    const componentDetail: {[x: string]: boolean[]} = {}
    Object.values(roleStore.compDetaileConfig).map(detailItem => {
      let lastCheckedArr: boolean[] = []
      detailItem.children && detailItem.children.length !== 0 && (lastCheckedArr = detailItem.children.map(item => {
        item.checked = ids.includes(item.id)
        return item.checked
      }))
      detailItem.checked = lastCheckedArr.every(Boolean)
      let list: boolean[] = componentDetail[detailItem.parentCode!]
      if (!list) {
        list = <boolean[]>[]
        componentDetail[detailItem.parentCode!] = list
      }
      // list.push(detailItem.checked)
      list.push(...lastCheckedArr)
    })
    // 处理第三层数据回填
    const pageDetail: {[x: string]: boolean[]} = {}
    const pageIndetDetail: {[x: string]: boolean[]} = {}
    Object.values(roleStore.componentConfig).map(compItem => {
      compItem.checked = componentDetail[compItem.code].every(Boolean)
      compItem.indeterminate = componentDetail[compItem.code].some(Boolean) && !componentDetail[compItem.code].every(Boolean)
      let list: boolean[] = pageDetail[compItem.parentCode!]
      if (!list) {
        list = <boolean[]>[]
        pageDetail[compItem.parentCode!] = list
      }
      list.push(compItem.checked)
      let indetList: boolean[] = pageIndetDetail[compItem.parentCode!]
      if (!indetList) {
        indetList = <boolean[]>[]
        pageIndetDetail[compItem.parentCode!] = indetList
      }
      indetList.push(compItem.indeterminate)
    })
    // 处理第二层数据回填
    const moduleDetail: {[x: string]: boolean[]} = {}
    const moduleIndet: {[x: string]: boolean[]} = {}
    Object.values(roleStore.pageConfig).map(pageItem => {
      const secondStatus = calCheckStatus(pageDetail[pageItem.code], pageIndetDetail[pageItem.code])
      pageItem.checked = secondStatus.checked
      pageItem.indeterminate = secondStatus.indeterminate
      // pageItem.checked = pageDetail[pageItem.code].every(Boolean)
      // pageItem.indeterminate = pageDetail[pageItem.code].some(Boolean) && !pageDetail[pageItem.code].every(Boolean)
      let list: boolean[] = moduleDetail[pageItem.parentCode!]
      if (!list) {
        list = <boolean[]>[]
        moduleDetail[pageItem.parentCode!] = list
      }
      list.push(pageItem.checked)
      let indetList: boolean[] = moduleIndet[pageItem.parentCode!]
      if (!indetList) {
        indetList = <boolean[]>[]
        moduleIndet[pageItem.parentCode!] = indetList
      }
      indetList.push(pageItem.indeterminate)
    })
    // 处理第一层数据回填
    const moduleCheckedArr: boolean[] = []
    const moduleIndetArr: boolean[] = []
    Object.values(roleStore.moduleConfig).map(moduleItem => {
      const firsetStatus = calCheckStatus(moduleDetail[moduleItem.code], moduleIndet[moduleItem.code])
      moduleItem.checked = firsetStatus.checked
      moduleItem.indeterminate = firsetStatus.indeterminate
      moduleCheckedArr.push(moduleItem.checked)
      moduleIndetArr.push(moduleItem.indeterminate)
      // moduleItem.checked = moduleDetail[moduleItem.code].every(Boolean)
      // moduleItem.indeterminate = moduleDetail[moduleItem.code].some(Boolean) && !moduleDetail[moduleItem.code].every(Boolean)
      // return moduleItem.checked
    })
    // 处理全选
    const checkAllStatus = calCheckStatus(moduleCheckedArr, moduleIndetArr)
    checkall.value = checkAllStatus.checked
    indeterminate.value = checkAllStatus.indeterminate
    // checkall.value = moduleCheckedArr.every(Boolean)
    // indeterminate.value = moduleCheckedArr.some(Boolean) && !moduleCheckedArr.every(Boolean)
  }
  //通过子项的checkbox状态计算父项的状态
  const calCheckStatus = (childCheckedArr: (boolean | undefined)[], childIndeterminateArr: (boolean | undefined)[]) => {
    return {
      checked: childCheckedArr.every(Boolean),
      indeterminate: childCheckedArr.concat(childIndeterminateArr).some(Boolean) && !childCheckedArr.every(Boolean)
    }
  }

  return {
    switchFirstLevel,
    switchSecondLevel,
    switchThirdLevel,
    switchLastLevel,
    clearAllCheck,
    getDataAndCheck,
    setCheckedStatus,
    calCheckStatus
  }
}

export default useUtils